package com.desuntech.utils
{
	import C4D.kbmMWConnection;
	import C4D.kbmMWEvent;
	import C4D.kbmMWRequest;
	import C4D.kbmMWResponse;
	
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.FileReference;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	
	import mx.controls.Alert;
	
	public class Amf3Service
	{
		private var _conn:kbmMWConnection;
		private var _serverDatetimeSuccessHandler:Function;
		private var _uploadFileSuccessHandler:Function;
		private var _downloadFileSuccessHandler:Function;
		private var _downloadFileProgressHandler:Function;
		private var _frUpload:FileReference;
		private var _frDownload:FileReference;
		private var _getDBKindHandler:Function;
		private var _getSoftwareKindHandler:Function;
		private var _fileName:String = 'default.ext';
		
		public function Amf3Service()
		{
		}
		
		public function set connection(conn:kbmMWConnection):void
		{
			_conn = conn;
		}
		
		// get server datetime
		public function getServerDatetime(resultHandler:Function):void {
			_serverDatetimeSuccessHandler = resultHandler;
			_conn.addEventListener(kbmMWEvent.DataAvailableEvent, getServerDatetime_ResultHandler);
			
			var req:kbmMWRequest = new kbmMWRequest();
			req.header.ServiceName = "Amf3Service";
			req.header.Function="GETSERVERDATETIME";
			_conn.Call(req);
		}
		
		private function getServerDatetime_ResultHandler(event:kbmMWEvent):void {
			_conn.removeEventListener(kbmMWEvent.DataAvailableEvent, getServerDatetime_ResultHandler);
			var result:kbmMWResponse;
			result = (event as kbmMWEvent).resultObject as kbmMWResponse;
			_serverDatetimeSuccessHandler(result.body.Result as Date);
		}
		
		// get database kind 
		public function getDatabaseKind(resultHandler:Function):void {
			_getDBKindHandler = resultHandler;
			
			var req:kbmMWRequest = new kbmMWRequest();
			req.header.ServiceName = "Amf3Service";
			req.header.Function="GETDATABASEKIND";
			_conn.Call(req, getDBKind_ResultHandler);
		}
		
		private function getDBKind_ResultHandler(result:kbmMWResponse):void {
			_getDBKindHandler(result.body.Result as String);
		}
		
		// get software kind  
		public function getSoftwareKind(resultHandler:Function):void {
			_getSoftwareKindHandler = resultHandler;
			_conn.addEventListener(kbmMWEvent.DataAvailableEvent, getSoftwareKind_ResultHandler);
			
			var req:kbmMWRequest = new kbmMWRequest();
			req.header.ServiceName = "Amf3Service";
			req.header.Function="GETSOFTWAREKIND";
			_conn.Call(req);
		}
		
		private function getSoftwareKind_ResultHandler(event:kbmMWEvent):void {
			_conn.removeEventListener(kbmMWEvent.DataAvailableEvent, getSoftwareKind_ResultHandler);
			var result:kbmMWResponse;
			result = (event as kbmMWEvent).resultObject as kbmMWResponse;
			_getSoftwareKindHandler(result.body.Result as String);
		}
		
		// upload file
		public function uploadFile(fileName:String, typeFilter:Array, resultHander:Function):void {
			_fileName = fileName;
			_uploadFileSuccessHandler = resultHander;
			
			_frUpload = new FileReference();
			_frUpload.addEventListener(Event.SELECT, onUploadSelectSelected);
			_frUpload.addEventListener(Event.CANCEL, onUploadSelectCanceled);
			_frUpload.browse(typeFilter);
		}
		
		private function onUploadSelectSelected(e:Event):void{
			_frUpload.removeEventListener(Event.SELECT, onUploadSelectSelected);
			_frUpload.removeEventListener(Event.CANCEL, onUploadSelectCanceled);
			
			_frUpload.addEventListener(Event.COMPLETE, onLoadComplete);
			_frUpload.addEventListener(IOErrorEvent.IO_ERROR, onLoadIOError);
			_frUpload.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onLoadSecurityError);
			_frUpload.load();
		}
		
		private function onUploadSelectCanceled(e:Event):void {
			_frUpload.removeEventListener(Event.SELECT, onUploadSelectSelected);
			_frUpload.removeEventListener(Event.CANCEL, onUploadSelectCanceled);
		}
		
		private function onLoadComplete(e:Event):void {
			_frUpload.removeEventListener(Event.COMPLETE, onLoadComplete);
			_frUpload.removeEventListener(IOErrorEvent.IO_ERROR, onLoadIOError);
			_frUpload.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onLoadSecurityError);
			
			var ba:ByteArray = (e.target as FileReference).data;
			_conn.addEventListener(kbmMWEvent.DataAvailableEvent, uploadFile_ResultHandler);
			
			var req:kbmMWRequest = new kbmMWRequest();
			req.header.ServiceName = "Amf3Service";
			req.header.Function = "PUTFILE";
			req.body.Args.push('.\\' + _fileName);
			req.body.Stream = ba;
			_conn.Call(req);
		}
		
		private function uploadFile_ResultHandler(event:kbmMWEvent):void {
			_conn.removeEventListener(kbmMWEvent.DataAvailableEvent, uploadFile_ResultHandler);
			var result:kbmMWResponse;
			result = (event as kbmMWEvent).resultObject as kbmMWResponse;
			_uploadFileSuccessHandler(result.body.Result as Boolean);
		}
		
		private function onLoadIOError(e:IOErrorEvent):void {
			_frUpload.removeEventListener(Event.COMPLETE, onLoadComplete);
			_frUpload.removeEventListener(IOErrorEvent.IO_ERROR, onLoadIOError);
			_frUpload.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onLoadSecurityError);
			Alert.show(e.toString(), 'IOErrorEvent');
		}
		
		private function onLoadSecurityError(e:SecurityErrorEvent):void {
			_frUpload.removeEventListener(Event.COMPLETE, onLoadComplete);
			_frUpload.removeEventListener(IOErrorEvent.IO_ERROR, onLoadIOError);
			_frUpload.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onLoadSecurityError);
			Alert.show(e.toString(), 'SecurityErrorEvent');
		}
		
		// download file
		/*public function downloadFile(resultHandler:Function):void {
		_downloadFileSuccessHandler = resultHandler;
		_conn.addEventListener(kbmMWEvent.DataAvailableEvent, downloadFile_ResultHandler);
		
		var req:kbmMWRequest = new kbmMWRequest();
		req.header.ServiceName = "Amf3Service";
		req.header.Function = "GETFILE";
		req.body.Args.push('.\\aaa.jpg');
		_conn.Call(req);
		}
		
		private function downloadFile_ResultHandler(event:kbmMWEvent):void {
		_conn.removeEventListener(kbmMWEvent.DataAvailableEvent, downloadFile_ResultHandler);
		
		var result:kbmMWResponse;
		result = (event as kbmMWEvent).resultObject as kbmMWResponse;
		var ba:ByteArray = result.body.Stream;
		var fr:FileReference = new FileReference();
		fr.addEventListener(Event.SELECT, onSaveFileSelected); 
		fr.save(ba, 'aaa.jpg');
		}*/
		
		public function downloadFile(url:String, filename:String, resultHandler:Function, progressHandler:Function):void {
			_downloadFileSuccessHandler = resultHandler;
			_downloadFileProgressHandler = progressHandler;
			
			var re:URLRequest = new URLRequest(url);
			_frDownload = new FileReference();
			_frDownload.addEventListener(Event.CANCEL, onDownloadSelectCanceled);
			_frDownload.addEventListener(Event.SELECT, onDownloadSelectSelected);
			
			_frDownload.addEventListener(ProgressEvent.PROGRESS, _downloadFileProgressHandler);
			_frDownload.addEventListener(Event.COMPLETE, onDownloadComplete);
			_frDownload.addEventListener(IOErrorEvent.IO_ERROR, onDownloadIOError);
			_frDownload.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onDownloadSecurityError);
			_frDownload.download(re, filename);
		}
		
		private function onDownloadSelectSelected(e:Event):void {
			_frDownload.removeEventListener(Event.CANCEL, onDownloadSelectCanceled);
			_frDownload.removeEventListener(Event.SELECT, onDownloadSelectSelected);
		}
		
		private function onDownloadSelectCanceled(e:Event):void {
			_frDownload.removeEventListener(Event.CANCEL, onDownloadSelectCanceled);
			_frDownload.removeEventListener(Event.SELECT, onDownloadSelectSelected);
			
			_frDownload.removeEventListener(ProgressEvent.PROGRESS, _downloadFileProgressHandler);
			_frDownload.removeEventListener(Event.COMPLETE, onDownloadComplete);
			_frDownload.removeEventListener(IOErrorEvent.IO_ERROR, onDownloadIOError);
			_frDownload.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onDownloadSecurityError);
		}
		
		private function onDownloadComplete(e:Event):void {
			_frDownload.removeEventListener(ProgressEvent.PROGRESS, _downloadFileProgressHandler);
			_frDownload.removeEventListener(Event.COMPLETE, onDownloadComplete);
			_frDownload.removeEventListener(IOErrorEvent.IO_ERROR, onDownloadIOError);
			_frDownload.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onDownloadSecurityError);
			
			_downloadFileSuccessHandler(true);
		}
		
		private function onDownloadIOError(e:IOErrorEvent):void {
			_frDownload.removeEventListener(ProgressEvent.PROGRESS, _downloadFileProgressHandler);
			_frDownload.removeEventListener(Event.COMPLETE, onDownloadComplete);
			_frDownload.removeEventListener(IOErrorEvent.IO_ERROR, onDownloadIOError);
			_frDownload.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onDownloadSecurityError);
			Alert.show(e.toString(), 'IOErrorEvent');
		}
		
		private function onDownloadSecurityError(e:SecurityErrorEvent):void {
			_frDownload.removeEventListener(ProgressEvent.PROGRESS, _downloadFileProgressHandler);
			_frDownload.removeEventListener(Event.COMPLETE, onDownloadComplete);
			_frDownload.removeEventListener(IOErrorEvent.IO_ERROR, onDownloadIOError);
			_frDownload.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onDownloadSecurityError);
			Alert.show(e.toString(), 'SecurityErrorEvent');
		}
		
		// get file
		public function getFile(url:String, resultHandler:Function):void {
			_downloadFileSuccessHandler = resultHandler;
			_conn.addEventListener(kbmMWEvent.DataAvailableEvent, downloadFile_ResultHandler);
			
			var req:kbmMWRequest = new kbmMWRequest();
			req.header.ServiceName = "Amf3Service";
			req.header.Function = "GETFILE";
			var ptn:RegExp = /\//g;
			var newUrl:String = url.replace(ptn, '\\');
			req.body.Args.push('.' + newUrl);
			_conn.Call(req);
		}
		
		private function downloadFile_ResultHandler(event:kbmMWEvent):void {
			_conn.removeEventListener(kbmMWEvent.DataAvailableEvent, downloadFile_ResultHandler);
			
			var result:kbmMWResponse;
			result = (event as kbmMWEvent).resultObject as kbmMWResponse;
			var ba:ByteArray = result.body.Stream;
			_downloadFileSuccessHandler(ba);
		}
	}
}